package com.kelvem.saas.workbanch.security.shiro;

import com.kelvem.saas.workbanch.core.system.model.SysUserEntity;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;

import java.security.SecureRandom;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

@Component
public class JwtUtil {

    public static String extractUsername(String token) {
        return extractClaim(token, Claims::getSubject);
    }

    public static Date extractExpiration(String token) {
        return extractClaim(token, Claims::getExpiration);
    }

    public static SysUserEntity extractUser(String token) {
        final Claims claims = extractAllClaims(token);
        SysUserEntity user = new SysUserEntity();
        user.setUsername(claims.getSubject());
        user.setOrgId(claims.get("orgId", Long.class));
        user.setAvatar(claims.get("avatar", String.class));
        user.setDisplayName(claims.get("displayName", String.class));
        return user;
    }

    public static <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = extractAllClaims(token);
        return claimsResolver.apply(claims);
    }

    private static Claims extractAllClaims(String token) {
        return Jwts.parser().setSigningKey(SecurityConstant.SECRET).build().parseClaimsJws(token).getBody();
    }

    private static Boolean isTokenExpired(String token) {
        return extractExpiration(token).before(new Date());
    }

    public static String generateToken(SysUserEntity user) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("orgId", user.getOrgId());
        claims.put("displayName", user.getDisplayName());
        claims.put("avatar", user.getAvatar());
        return createToken(claims, user.getUsername());
    }

    private static String createToken(Map<String, Object> claims, String subject) {
        // 创建 JWT
        String jwt = Jwts.builder()
                .setClaims(claims)
                .setSubject(subject)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + SecurityConstant.EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS256, SecurityConstant.SECRET)
                .compact();
        return jwt;
    }

    public static Boolean validateToken(String token, String username) {
        final String extractedUsername = extractUsername(token);
        return (extractedUsername.equals(username) && !isTokenExpired(token));
    }

    private JwtUtil() {
        // do nothing
    }

    public static String GenerateSecureKeyHS256() {
        try {
            // 创建一个安全随机数生成器实例
            SecureRandom secureRandom = new SecureRandom();

            // 生成一个 256 位 (32 字节) 的随机字节数组
            byte[] keyBytes = new byte[32];
            secureRandom.nextBytes(keyBytes);

            // 使用 Base64 对密钥字节数组进行编码
            String encodedKey = Base64.getEncoder().encodeToString(keyBytes);

            // 输出密钥字符串
            System.out.println("Generated Key: " + encodedKey);

            return encodedKey;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}
